home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 15 / Example 15.2 / player.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-06-30  |  6.9 KB  |  270 lines

  1. #include "player.h"        
  2.  
  3. //Player Shaders
  4. SHADER lighting, teamCol;
  5. D3DXHANDLE worldHandle, viewProjHandle, sunHandle, teamColHandle, vertexCol;
  6. ID3DXLine *selLine = NULL;
  7.  
  8. extern NETWORK network;
  9.  
  10. void LoadPlayerResources(IDirect3DDevice9* m_pDevice)
  11. {
  12.     //Setup shaders
  13.     lighting.Init(m_pDevice, "shaders/lighting.vs", VERTEX_SHADER);
  14.     worldHandle = lighting.GetConstant("matW");
  15.     viewProjHandle = lighting.GetConstant("matVP");
  16.     sunHandle = lighting.GetConstant("DirToSun");
  17.     vertexCol = lighting.GetConstant("vertexCol");
  18.  
  19.     teamCol.Init(m_pDevice, "shaders/teamCol.ps", PIXEL_SHADER);
  20.     teamColHandle = teamCol.GetConstant("tmCol");
  21.  
  22.     //Line for unit selection
  23.     D3DXCreateLine(m_pDevice, &selLine);
  24. }
  25.  
  26. void UnloadPlayerResources()
  27. {
  28.     if(selLine != NULL)
  29.         selLine->Release();
  30.     selLine = NULL;
  31. }
  32.  
  33. //////////////////////////////////////////////////////////////////////////////////
  34. //                                PLAYER                                            //
  35. //////////////////////////////////////////////////////////////////////////////////
  36.  
  37. PLAYER::PLAYER(int _teamNo, D3DXVECTOR4 _teamCol, INTPOINT startPos, TERRAIN* _terrain, IDirect3DDevice9* _Device)
  38. {
  39.     m_teamNo = _teamNo;
  40.     m_teamColor = _teamCol;
  41.     m_pTerrain = _terrain;
  42.     m_pDevice = _Device;
  43.     m_areaSelect = false;
  44.  
  45.     if(m_pTerrain == NULL)return;
  46.  
  47.     //Add a few buildings
  48.     for(int i=0;i<3;i++)
  49.     {
  50.         INTPOINT p = FindClosestBuildingLocation(i, startPos);
  51.  
  52.         if(m_pTerrain->Within(p))
  53.             AddMapObject(i, p, true);
  54.     }
  55.  
  56.     //Also add a few units
  57.     for(int i=0;i<6;i++)
  58.     {
  59.         INTPOINT mp;
  60.         bool ok = false;
  61.         do
  62.         {
  63.             mp.x = rand()%20 - 10 + startPos.x;
  64.             mp.y = rand()%20 - 10 + startPos.y;
  65.  
  66.             MAPTILE *tile = m_pTerrain->GetTile(mp);
  67.             if(tile != NULL)ok = tile->m_walkable && tile->m_pMapObject == NULL;
  68.         }
  69.         while(!ok);
  70.  
  71.         AddMapObject(i % 3, mp, false);
  72.     }
  73. }
  74.  
  75. PLAYER::~PLAYER()
  76. {
  77.     for(int i=0;i<m_mapObjects.size();i++)
  78.         if(m_mapObjects[i] != NULL)
  79.             delete m_mapObjects[i];
  80. }
  81.  
  82. void PLAYER::AddMapObject(int type, INTPOINT mp, bool isBuilding)
  83. {
  84.     if(isBuilding)
  85.         m_mapObjects.push_back(new BUILDING(type, m_teamNo, mp, m_pTerrain, true, m_pDevice));
  86.     else m_mapObjects.push_back(new UNIT(type, m_teamNo, mp, m_pTerrain, m_pDevice));
  87. }
  88.  
  89. void PLAYER::RenderMapObjects(CAMERA &camera)
  90. {
  91.     D3DXMATRIX identity;
  92.     D3DXMatrixIdentity(&identity);
  93.     
  94.     lighting.SetMatrix(viewProjHandle, camera.GetViewMatrix() * camera.GetProjectionMatrix());
  95.  
  96.     //Sun direction
  97.     D3DXVECTOR3 sun;
  98.     D3DXVec3Normalize(&sun, &D3DXVECTOR3(0.5f, 1.0f, -0.5));
  99.     lighting.SetVector3(sunHandle, sun);
  100.  
  101.     //Team color
  102.     teamCol.SetVector4(teamColHandle, m_teamColor);
  103.  
  104.     //Vertex color
  105.     lighting.SetVector4(vertexCol, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f));
  106.  
  107.     lighting.Begin();
  108.     teamCol.Begin();
  109.  
  110.     //Render units
  111.     for(int i=0;i<m_mapObjects.size();i++)
  112.         if(m_mapObjects[i] != NULL)
  113.             if(!camera.Cull(m_mapObjects[i]->GetBoundingBox()))
  114.             {
  115.                 if(m_mapObjects[i]->m_isBuilding)
  116.                     lighting.SetMatrix(worldHandle, m_mapObjects[i]->GetWorldMatrix());
  117.                 else lighting.SetMatrix(worldHandle, identity);
  118.  
  119.                 m_mapObjects[i]->Render();
  120.             }
  121.  
  122.     teamCol.End();
  123.     lighting.End();
  124. }
  125.  
  126. void PLAYER::PaintSelectedMapObjects(CAMERA &camera)
  127. {
  128.     //Paint selected map objects
  129.     for(int i=0;i<m_mapObjects.size();i++)
  130.         if(m_mapObjects[i] != NULL)
  131.             if(!camera.Cull(m_mapObjects[i]->GetBoundingBox()))
  132.                 m_mapObjects[i]->PaintSelected();
  133. }
  134.  
  135. void PLAYER::UpdateMapObjects(float deltaTime)
  136. {
  137.     for(int i=0;i<m_mapObjects.size();i++)
  138.         if(m_mapObjects[i] != NULL)
  139.             m_mapObjects[i]->Update(deltaTime);
  140. }
  141.  
  142. INTPOINT PLAYER::FindClosestBuildingLocation(int buildType, INTPOINT mp)
  143. {
  144.     //i = Search Radius
  145.     for(int i=0;i<30;i++)
  146.     {
  147.         for(int x=mp.x - i;x<=mp.x + i;x++)
  148.         {
  149.             if(PlaceOk(buildType, INTPOINT(x, mp.y - i), m_pTerrain))return INTPOINT(x, mp.y - i);
  150.             if(PlaceOk(buildType, INTPOINT(x, mp.y + i), m_pTerrain))return INTPOINT(x, mp.y + i);
  151.         }
  152.  
  153.         for(int y=mp.y - i;y<=mp.y + i;y++)
  154.         {
  155.             if(PlaceOk(buildType, INTPOINT(mp.x - i, y), m_pTerrain))return INTPOINT(mp.x - i, y);
  156.             if(PlaceOk(buildType, INTPOINT(mp.x + i, y), m_pTerrain))return INTPOINT(mp.x + i, y);
  157.         }
  158.     }
  159.  
  160.     //No good place found
  161.     return INTPOINT(-1, -1);
  162. }
  163.  
  164. void PLAYER::Select(MOUSE &mouse)
  165. {
  166.     try
  167.     {
  168.         if(mouse.ClickLeft())    // If the mouse button is pressed
  169.         {                
  170.             for(int i=0;i<m_mapObjects.size();i++)    //Deselect all mapObjects
  171.                 m_mapObjects[i]->m_selected = false;
  172.  
  173.             if(!m_areaSelect)        // If no area selection is in progress
  174.             {    
  175.                 //Find closest mapObjects
  176.                 int mapObject = -1;
  177.                 float bestDist = 100000.0f;
  178.  
  179.                 D3DXMATRIX world;
  180.                 D3DXMatrixIdentity(&world);
  181.                 m_pDevice->SetTransform(D3DTS_WORLD, &world);
  182.                 RAY ray = mouse.GetRay();
  183.  
  184.                 for(int i=0;i<m_mapObjects.size();i++)
  185.                 {                    
  186.                     float dist = ray.Intersect(m_mapObjects[i]->GetBoundingBox());
  187.  
  188.                     if(dist >= 0.0f && dist < bestDist)
  189.                     {
  190.                         mapObject = i;
  191.                         bestDist = dist;
  192.                     }
  193.                 }
  194.                 if(mapObject > -1)
  195.                     m_mapObjects[mapObject]->m_selected = true;
  196.                 else
  197.                 {
  198.                     m_areaSelect = true;        // if no unit if found,                                             
  199.                     m_startSel = mouse;        // start area selection
  200.                 }
  201.             }
  202.             else    //Area Selection in progress
  203.             {
  204.                 // Create area rectangle
  205.                 INTPOINT p1 = m_startSel, p2 = mouse;
  206.                 if(p1.x > p2.x){int temp = p2.x;p2.x = p1.x;p1.x = temp;}
  207.                 if(p1.y > p2.y){int temp = p2.y;p2.y = p1.y;p1.y = temp;}
  208.                 RECT selRect = {p1.x, p1.y, p2.x, p2.y};
  209.  
  210.                 //Draw selection rectangle
  211.                 D3DXVECTOR2 box[] = {D3DXVECTOR2(p1.x, p1.y), D3DXVECTOR2(p2.x, p1.y), 
  212.                                      D3DXVECTOR2(p2.x, p2.y), D3DXVECTOR2(p1.x, p2.y), 
  213.                                      D3DXVECTOR2(p1.x, p1.y)};
  214.  
  215.                 selLine->SetWidth(1.0f);
  216.                 selLine->Begin();
  217.                 selLine->Draw(box, 5, 0xffffffff);                
  218.                 selLine->End();
  219.  
  220.                 //Select any units inside our rectangle
  221.                 for(int i=0;i<m_mapObjects.size();i++)
  222.                     if(m_mapObjects[i] != NULL && !m_mapObjects[i]->m_isBuilding)
  223.                     {
  224.                         INTPOINT p = GetScreenPos(m_mapObjects[i]->m_position, m_pDevice);
  225.                         if(p.inRect(selRect))m_mapObjects[i]->m_selected = true;
  226.                     }
  227.             }
  228.         }
  229.         else if(m_areaSelect)        //Stop area selection
  230.             m_areaSelect = false;
  231.  
  232.     }
  233.     catch(...)
  234.     {
  235.         debug.Print("Error in PLAYER::Select()");
  236.     }
  237. }
  238.  
  239. void PLAYER::UnitOrders(MOUSE &mouse)
  240. {
  241.     if(mouse.ClickRight())
  242.     {
  243.         mouse.DisableInput(300);
  244.  
  245.         for(int i=0;i<m_mapObjects.size();i++)
  246.             if(m_mapObjects[i] != NULL)
  247.                 if(!m_mapObjects[i]->m_isBuilding && m_mapObjects[i]->m_selected)
  248.                 {
  249.                     //Cast to UNIT
  250.                     UNIT *unit = (UNIT*)m_mapObjects[i];
  251.                     unit->MoveTo(mouse.m_mappos, false, true);
  252.  
  253.                     //Send network command
  254.                     network.Send(new MSG_ORDER(m_teamNo, i, mouse.m_mappos), true);
  255.                 }
  256.     }
  257. }
  258.  
  259. INTPOINT PLAYER::GetCenter()
  260. {
  261.     INTPOINT p;
  262.  
  263.     for(int i=0;i<m_mapObjects.size();i++)
  264.         if(m_mapObjects[i] != NULL)
  265.             p += m_mapObjects[i]->m_mappos;
  266.  
  267.     p /= m_mapObjects.size();
  268.  
  269.     return p;
  270. }